﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Configuration;
using MySql.Data.MySqlClient;
using System.Windows.Documents;

namespace WpfApplication1.Class.Bean
{ 
    public class BaseObject<T> 
    {

        private long id;
        public long Id
        {
            get { return id; }
            set { id = value; }
        }
        
        public static string getTable()
        {
            string tableName =  typeof(T).Name;
            tableName = tableName.Substring(5);
            tableName = tableName.ToLower();
            return tableName;
        }

        #region SaveOrUpdate
        public static void SaveOrUpdate(T obj)
        {
            using (MySqlConnection connexion = new MySqlConnection(ConfigurationManager.ConnectionStrings["maConnexion"].ConnectionString))
            {
                string tableName = getTable();
                connexion.Open();
                MySqlCommand cmd = new MySqlCommand();
                string req = "";
                

                MySqlCommand cmd2 = new MySqlCommand();
                string req2 = "Select * from " + tableName + " where Id = ?id";
                cmd2.Parameters.AddWithValue("?id", long.Parse(obj.GetType().GetProperty("Id").GetValue(obj).ToString()));
                cmd2.Connection = connexion;
                cmd2.CommandText = req2;
                
                Dictionary<string, Type> fields = new Dictionary<string, Type>();
                using (MySqlDataReader dataReader = cmd2.ExecuteReader())
                {
                    for (int i = 0; i < dataReader.FieldCount; i++)
                    {
                        fields[dataReader.GetName(i)] = dataReader.GetFieldType(i);
                    }
                }


                #region update
                if (long.Parse(obj.GetType().GetProperty("Id").GetValue(obj).ToString()) != 0)
                {
                    T current = (T)Activator.CreateInstance(typeof(T));
                    T current2 =Read(long.Parse(obj.GetType().GetProperty("Id").GetValue(obj).ToString()),current);
                    req = "UPDATE " + tableName + " SET ";


                    foreach (string key in fields.Keys)
                    {


                        if (!obj.GetType().GetProperty(key).GetValue(obj).Equals(current2.GetType().GetProperty(key).GetValue(current2)))
                            current2.GetType().GetProperty(key).SetValue(current2, obj.GetType().GetProperty(key).GetValue(obj)); 

                        if (key != "Id")
                        {
                            req += key + " = " + "?" + key + " , ";
                            cmd.Parameters.AddWithValue("?" + key, current2.GetType().GetProperty(key).GetValue(current2));
                        }
                    }

                    req = req.Substring(0, req.Count() - 2);
                    req += " WHERE Id = ?id";


                    cmd.Parameters.AddWithValue("?id", long.Parse(obj.GetType().GetProperty("Id").GetValue(obj).ToString()));
                }
                #endregion

                #region INsert
                else
                {
                    req = "INSERT INTO " + tableName + " ( ";
                    foreach (string key in fields.Keys)
                    {
                        if(key!="Id")
                            req += " " + key + " , ";
                        
                    }
                    req = req.Substring(0, req.Count() - 2);
                    req+=" ) VALUES ( ";
                    foreach (string key in fields.Keys)
                    {
                        if (key != "Id")
                        {
                            req += " ?" + key + " ";
                            cmd.Parameters.AddWithValue("?" + key, obj.GetType().GetProperty(key).GetValue(obj));
                            req += ", ";
                        }
                    }
                    req = req.Substring(0, req.Count() - 2);
                    req += ")";
                }
                #endregion

                
                cmd.Connection = connexion;
                cmd.CommandText = req;
                cmd.ExecuteNonQuery();


            }
        }
        #endregion

        #region read
        public static T Read(long id, T obj)
        {
            using (MySqlConnection connexion = new MySqlConnection(ConfigurationManager.ConnectionStrings["maConnexion"].ConnectionString))
            {
                
                Dictionary<string, Dictionary<Type, object>> test = new Dictionary<string, Dictionary<Type, object>>();

                string tableName = getTable();
                connexion.Open();
                MySqlCommand cmd = new MySqlCommand();
                string req = "Select * from " + tableName + " where Id = ?id";
                cmd.Parameters.AddWithValue("?id", id);
                cmd.Connection = connexion;
                cmd.CommandText = req;
                bool verif = false;
                using (MySqlDataReader dataReader = cmd.ExecuteReader())
                {
                    verif = dataReader.HasRows;
                    while (dataReader.Read())
                    {
                        for(int i = 0; i < dataReader.FieldCount; i++)
                        {
                            Dictionary<Type,object> champ = new Dictionary<Type,object>();
                            
                            champ[dataReader[i].GetType()] = dataReader[dataReader.GetName(i)];
                            test[dataReader.GetName(i)] = champ;
                        }
                    }
                }

                

                
                foreach (string key in test.Keys)
                {
                    obj.GetType().GetProperty(key).SetValue(obj, test[key].First().Value);
                }
                if (!verif)
                    return default(T);
                else
                    return obj;
            }
        }

        #endregion

        public static List<T> Search(List<SearchField> ls)
        {
            string tableName = getTable();
            List<T> list = new List<T>();

            using (MySqlConnection connexion = new MySqlConnection(ConfigurationManager.ConnectionStrings["maConnexion"].ConnectionString))
            {
                connexion.Open();
                MySqlCommand cmd = new MySqlCommand();
                string req ="Select * from " + tableName+"";
                if (ls.Count != 0)
                {
                    req += " where ";

                    foreach (SearchField fields in ls)
                    {
                        req += fields.FieldName + " " + fields.Comparator + " " + "?" + fields.FieldName + " AND ";
                        cmd.Parameters.AddWithValue("?" + fields.FieldName, fields.ValueField);
                    }
                    req = req.Substring(0, req.Count() - 4);
                }
                cmd.Connection = connexion;
                cmd.CommandText = req;
                using (MySqlDataReader dataReader = cmd.ExecuteReader())
                {
                    
                    while (dataReader.Read())
                    {
                        T current = (T)Activator.CreateInstance(typeof(T));
                        T obj = BaseObject<T>.Read((long)(dataReader["Id"]), current);
                        list.Add(obj);
                    }
                }
            }
            return list;

            
            
        }


        public static void Delete(T obj)
        {

        }


    }
}
